<template>
  <div class="image-carousel-app">
    <!-- 图片展示区域 -->
    <div class="carousel-container" :style="{ height: height }">
      <!-- 单张图片 -->
      <div v-if="imageList.length === 1" class="single-image">
        <img 
          :src="imageList[0].url || imageList[0]" 
          :alt="imageList[0].name || '图片'"
          @error="handleImageError"
          @click="handleImageClick(imageList[0], 0)"
        />
      </div>
      
      <!-- 多张图片轮播 -->
      <div v-else-if="imageList.length > 1" class="carousel-wrapper">
        <!-- 图片列表 -->
        <div 
          class="carousel-list" 
          :style="{ transform: `translateX(-${currentIndex * 100}%)` }"
        >
          <div 
            v-for="(image, index) in imageList" 
            :key="index"
            class="carousel-item"
          >
            <img 
              :src="image.url || image" 
              :alt="image.name || `图片${index + 1}`"
              @error="handleImageError"
              @click="handleImageClick(image, index)"
            />
          </div>
        </div>
        
        <!-- 指示器 -->
        <div v-if="showIndicators" class="carousel-indicators">
          <span 
            v-for="(_, index) in imageList" 
            :key="index"
            class="indicator"
            :class="{ active: index === currentIndex }"
            @click="goToSlide(index)"
          ></span>
        </div>
        
        <!-- 导航按钮 -->
        <div v-if="showNavigation" class="carousel-navigation">
          <button 
            class="nav-btn prev-btn" 
            @click="prevSlide"
            :disabled="currentIndex === 0"
          >
            <i class="icon-arrow-left"></i>
          </button>
          <button 
            class="nav-btn next-btn" 
            @click="nextSlide"
            :disabled="currentIndex === imageList.length - 1"
          >
            <i class="icon-arrow-right"></i>
          </button>
        </div>
        
        <!-- 图片计数器 -->
        <div v-if="showCounter" class="carousel-counter">
          {{ currentIndex + 1 }} / {{ imageList.length }}
        </div>
      </div>
      
      <!-- 无图片状态 -->
      <div v-else class="no-image">
        <i class="icon-picture no-image-icon"></i>
        <span class="no-image-text">{{ noImageText }}</span>
      </div>
    </div>
    
    <!-- 缩略图列表 -->
    <div v-if="showThumbnails && imageList.length > 1" class="thumbnail-list">
      <div 
        v-for="(image, index) in imageList" 
        :key="index"
        class="thumbnail-item"
        :class="{ active: index === currentIndex }"
        @click="goToSlide(index)"
      >
        <img 
          :src="image.url || image" 
          :alt="image.name || `缩略图${index + 1}`"
          @error="handleImageError"
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'

// Props定义
interface Props {
  /** 图片列表，支持字符串URL或FileInfo对象 */
  images: (string | FileInfo)[]
  /** 组件高度 */
  height?: string
  /** 是否显示指示器 */
  showIndicators?: boolean
  /** 是否显示导航按钮 */
  showNavigation?: boolean
  /** 是否显示计数器 */
  showCounter?: boolean
  /** 是否显示缩略图 */
  showThumbnails?: boolean
  /** 自动播放间隔（毫秒），0表示不自动播放 */
  autoplay?: number
  /** 无图片时显示的文字 */
  noImageText?: string
  /** 是否循环播放 */
  loop?: boolean
}

// FileInfo接口
interface FileInfo {
  url: string
  name?: string
  size?: number
  type?: string
}

const props = withDefaults(defineProps<Props>(), {
  height: '200px',
  showIndicators: true,
  showNavigation: true,
  showCounter: true,
  showThumbnails: false,
  autoplay: 0,
  noImageText: '暂无图片',
  loop: true
})

// Emits定义
const emit = defineEmits<{
  'image-click': [image: string | FileInfo, index: number]
  'change': [index: number]
}>()

// 响应式数据
const currentIndex = ref(0)
const autoplayTimer = ref<NodeJS.Timeout | null>(null)

// 计算属性
const imageList = computed(() => {
  if (!props.images || props.images.length === 0) {
    return []
  }
  return props.images
})

// 方法
const goToSlide = (index: number) => {
  if (index >= 0 && index < imageList.value.length) {
    currentIndex.value = index
    emit('change', index)
  }
}

const nextSlide = () => {
  if (props.loop && currentIndex.value === imageList.value.length - 1) {
    goToSlide(0)
  } else if (currentIndex.value < imageList.value.length - 1) {
    goToSlide(currentIndex.value + 1)
  }
}

const prevSlide = () => {
  if (props.loop && currentIndex.value === 0) {
    goToSlide(imageList.value.length - 1)
  } else if (currentIndex.value > 0) {
    goToSlide(currentIndex.value - 1)
  }
}

const handleImageClick = (image: string | FileInfo, index: number) => {
  emit('image-click', image, index)
}

const handleImageError = (event: Event) => {
  const img = event.target as HTMLImageElement
  img.style.display = 'none'
}

const startAutoplay = () => {
  if (props.autoplay > 0 && imageList.value.length > 1) {
    autoplayTimer.value = setInterval(() => {
      nextSlide()
    }, props.autoplay)
  }
}

const stopAutoplay = () => {
  if (autoplayTimer.value) {
    clearInterval(autoplayTimer.value)
    autoplayTimer.value = null
  }
}

// 监听图片列表变化
watch(imageList, (newList) => {
  if (newList.length === 0) {
    currentIndex.value = 0
  } else if (currentIndex.value >= newList.length) {
    currentIndex.value = newList.length - 1
  }
  
  // 重新启动自动播放
  if (props.autoplay > 0) {
    stopAutoplay()
    startAutoplay()
  }
}, { immediate: true })

// 生命周期
onMounted(() => {
  startAutoplay()
})

onUnmounted(() => {
  stopAutoplay()
})
</script>

<style lang="scss" scoped>
.image-carousel-app {
  width: 100%;
  
  .carousel-container {
    position: relative;
    width: 100%;
    overflow: hidden;
    background-color: #f8f9fa;
    border-radius: 12px;
    
    .single-image {
      width: 100%;
      height: 100%;
      display: flex;
      align-items: center;
      justify-content: center;
      
      img {
        max-width: 100%;
        max-height: 100%;
        object-fit: contain;
        border-radius: 12px;
      }
    }
    
    .carousel-wrapper {
      position: relative;
      width: 100%;
      height: 100%;
      
      .carousel-list {
        display: flex;
        width: 100%;
        height: 100%;
        transition: transform 0.3s ease;
        
        .carousel-item {
          flex-shrink: 0;
          width: 100%;
          height: 100%;
          display: flex;
          align-items: center;
          justify-content: center;
          
          img {
            max-width: 100%;
            max-height: 100%;
            object-fit: contain;
            border-radius: 12px;
          }
        }
      }
      
      .carousel-indicators {
        position: absolute;
        bottom: 16px;
        left: 50%;
        transform: translateX(-50%);
        display: flex;
        gap: 8px;
        z-index: 10;
        
        .indicator {
          width: 8px;
          height: 8px;
          border-radius: 50%;
          background-color: rgba(255, 255, 255, 0.5);
          cursor: pointer;
          transition: all 0.3s ease;
          
          &:hover {
            background-color: rgba(255, 255, 255, 0.8);
          }
          
          &.active {
            background-color: #fff;
            transform: scale(1.2);
          }
        }
      }
      
      .carousel-navigation {
        position: absolute;
        top: 50%;
        left: 0;
        right: 0;
        transform: translateY(-50%);
        display: flex;
        justify-content: space-between;
        padding: 0 16px;
        z-index: 10;
        
        .nav-btn {
          width: 40px;
          height: 40px;
          border: none;
          border-radius: 50%;
          background-color: rgba(0, 0, 0, 0.5);
          color: #fff;
          cursor: pointer;
          display: flex;
          align-items: center;
          justify-content: center;
          transition: all 0.3s ease;
          
          &:hover:not(:disabled) {
            background-color: rgba(0, 0, 0, 0.7);
            transform: scale(1.1);
          }
          
          &:disabled {
            opacity: 0.3;
            cursor: not-allowed;
          }
          
          i {
            font-size: 18px;
          }
        }
      }
      
      .carousel-counter {
        position: absolute;
        top: 16px;
        right: 16px;
        background-color: rgba(0, 0, 0, 0.5);
        color: #fff;
        padding: 8px 12px;
        border-radius: 20px;
        font-size: 12px;
        z-index: 10;
      }
    }
    
    .no-image {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      color: #909399;
      
      .no-image-icon {
        font-size: 48px;
        margin-bottom: 16px;
        opacity: 0.5;
      }
      
      .no-image-text {
        font-size: 14px;
      }
    }
  }
  
  .thumbnail-list {
    display: flex;
    margin-top: 12px;
    overflow-x: auto;
    
    .thumbnail-item {
      flex-shrink: 0;
      width: 60px;
      height: 60px;
      border-radius: 8px;
      overflow: hidden;
      cursor: pointer;
      border: 2px solid transparent;
      transition: all 0.3s ease;
      margin-right: 8px;
      
      &:last-child {
        margin-right: 0;
      }
      
      &:hover {
        border-color: #409eff;
        transform: scale(1.05);
      }
      
      &.active {
        border-color: #409eff;
        box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
      }
      
      img {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }
    }
  }
}

// 图标样式
.icon-arrow-left::before {
  content: "‹";
  font-size: 24px;
  font-weight: bold;
}

.icon-arrow-right::before {
  content: "›";
  font-size: 24px;
  font-weight: bold;
}

.icon-picture::before {
  content: "🖼️";
  font-size: 48px;
}

// 响应式设计
@media (max-width: 480px) {
  .image-carousel-app {
    .carousel-container {
      .carousel-wrapper {
        .carousel-navigation {
          .nav-btn {
            width: 36px;
            height: 36px;
            
            i {
              font-size: 16px;
            }
          }
        }
        
        .carousel-indicators {
          .indicator {
            width: 6px;
            height: 6px;
            margin: 0 3px;
          }
        }
      }
    }
    
    .thumbnail-list {
      .thumbnail-item {
        width: 50px;
        height: 50px;
        margin-right: 6px;
      }
    }
  }
}
</style>
